
#include <BFile>
#include <BFolder>
#include <BReadWrite>
#include "member_BStyleDocument.h"
#include "member_BWidget.h"
#include "member_BStyle.h"

using namespace BWE;

#define member					(*(member_BStyleDocument*)_ptr)
#define member_allocate()		_ptr = new member_BStyleDocument(this)
#define member_release()		delete (member_BStyleDocument*)_ptr

BStyleDocument::BStyleDocument()
{
	member_allocate();
}
BStyleDocument::~BStyleDocument()
{
	member_release();
}

void BStyleDocument::setPath(const BString& path)
{
	member.path = path;
}
const BString& BStyleDocument::path() const
{
	return member.path;
}

BStyle* BStyleDocument::load(const BString& fileName)
{
	BString& message = member.message.fill<BString>();
	message.clear();
	BString text;
	if (!ReadText(fileName, text))
	{
		message << "\tError : open file failed." << '\n';
		return 0;
	}
	member.path = fileName.path();
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	BStyle* style = new BStyle();
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
		this->emit(Signal_Error, message);
	else if (message.size())
		this->emit(Signal_Message, message);
	return style;
}
bool BStyleDocument::load(const BString& fileName, BStyle* style)
{
	BString& message = member.message.fill<BString>();
	message.clear();
	BString text;
	if (!ReadText(fileName, text))
	{
		message << "\tError : open file failed." << '\n';
		return 0;
	}
	member.error = false;
	member.path = fileName.path();
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
	{
		this->emit(Signal_Error, message);
		return false;
	}
	if (message.size())
		this->emit(Signal_Message, message);
	return true;
}
bool BStyleDocument::save(const BString& fileName, const BStyle* style) const
{
	return true;
}

BStyle* BStyleDocument::read(const BStream& stream)
{
	BString& message = member.message.fill<BString>();
	message.clear();
	member.error = false;
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	BString text;
	stream.read(text);
	BStyle* style = new BStyle();
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
		this->emit(Signal_Error, message);
	else if (message.size())
		this->emit(Signal_Message, message);
	return style;
}
bool BStyleDocument::read(const BStream& stream, BStyle* style)
{
	BString& message = member.message.fill<BString>();
	message.clear();
	member.error = false;
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	BString text;
	stream.read(text);
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
	{
		this->emit(Signal_Error, message);
		return false;
	}
	if (message.size())
		this->emit(Signal_Message, message);
	return true;
}
bool BStyleDocument::write(BStream& text, const BStyle* style) const
{
	return false;
}

BStyle* BStyleDocument::read(const BString& text)
{
	BString& message = member.message;
	message.clear();
	member.error = false;
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	BStyle* style = new BStyle();
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
		this->emit(Signal_Error, message);
	else if (message.size())
		this->emit(Signal_Message, message);
	return style;
}
bool BStyleDocument::read(const BString& text, BStyle* style)
{
	BString& message = member.message.fill<BString>();
	message.clear();
	member.error = false;
	member.lineNumber = 1;
	member.linePos = 0;
	member.imageMap.clear();
	int pos = 0;
	member.read(style, text, pos);
	if (pos < text.size())
		message << "\tWarning : document stop at " << pos << '/' << text.size() << '\n';
	if (member.error)
	{
		this->emit(Signal_Error, message);
		return false;
	}
	if (message.size())
		this->emit(Signal_Message, message);
	return true;
}
bool BStyleDocument::write(BString& text, const BStyle* style) const
{
	BString& message = member.message.fill<BString>();
	message.clear();
	text.reset();
	if (!style)
		return false;
	member.write(style, text, 0);
	if (member.error)
	{
		this->emit(Signal_Error, message);
		return false;
	}
	if (message.size())
		this->emit(Signal_Message, message);
	return true;
}

int BStyleDocument::imageCount() const
{
	return member.imageMap.size();
}
BImage* BStyleDocument::image(int index)
{
	return member.imageMap.seek(index).value();
}
const BImage* BStyleDocument::image(int index) const
{
	return member.imageMap.seek(index).value();
}

const BString& BStyleDocument::message() const
{
	BString& message = member.message;
	return message;
}
